import SoundManager, { ClipPlayingInfo, SoundGrille, SoundGrilleNode } from "./sound_manager";
import Utils from "./utils";


export default class BGMManager extends SoundGrilleNode {
    channels: ClipPlayingInfo[] = [];
    fadeTime = 0.3;

    play(nameOrClip: string | cc.AudioClip, channelInd = 0, targetVolume = 1) {
        let prevCp = this.channels[channelInd];
        if (prevCp) {
            if (prevCp.playName === nameOrClip || prevCp.clip === nameOrClip) {
                return;
            }
        }
        let nextCp = SoundManager.ins.playClip(nameOrClip, true, 0);

        targetVolume *= this.getGrilleFactor();
        cc.tween(nextCp).to(this.fadeTime, { volume: targetVolume }).start();

        if (prevCp) {
            cc.tween(prevCp).to(this.fadeTime, { volume: 0 }).call(() => {
                prevCp.stop();
            }).start();
        }

        this.channels[channelInd] = nextCp;
        return nextCp;
    }

    stop(channelInd = 0) {
        let prevCp = this.channels[channelInd];
        delete this.channels[channelInd];
        if (prevCp) {
            cc.tween(prevCp).to(this.fadeTime, { volume: 0 }).call(() => {
                prevCp.stop();
            }).start();
        }
    }

    //使用播放名停止播放（停止寻找到的第一个频道）
    stopByName(playName: string) {
        this.channels.forEach((cp, ind) => {
            if (cp.playName === playName) {
                this.stop(ind);
                return false;
            }
        });
    }

    grilles: SoundGrille[] = [];
    addGrille(key, factor) {
        if (this.grilles.find(ele => ele.key === key)) {
            return;
        }
        let sg = new SoundGrille();
        sg.key = key;
        sg.factor = factor;
        this.grilles.push(sg);
        this.onGrilleAdd(sg);
    }
    getGrilleFactor() {
        let factor = 1.0;
        this.grilles.forEach(sg => {
            factor *= sg.factor;
        });
        return factor;
    }
    delGrille(key) {
        let ind = this.grilles.findIndex(ele => ele.key === key);
        if (ind !== -1) {
            this.onGrilleRemove(this.grilles.splice(ind, 1)[0]);
        }
    }
    onGrilleAdd(sg: SoundGrille) {
        this.channels.forEach(ch => {
            ch.volume *= sg.factor;
        });
    }
    onGrilleRemove(sg: SoundGrille) {
        this.channels.forEach(ch => {
            ch.volume /= sg.factor;
        });
    }

    private static __ins = null;
    static get ins(): BGMManager {
        if (!this.__ins) {
            this.__ins = new BGMManager();
        }
        return this.__ins;
    }

};


window["bgm"] = BGMManager;